package com.nxy.cpfsfe.busi.btmgtsk;

import com.adtec.starring.datapool.EPOper;
import com.adtec.starring.exception.BaseException;
import com.adtec.starring.struct.dta.DtaInfo;
import com.adtec.starring.util.SpringUtil;
import com.nxy.cpfsfe.ToParmMapResultHandler;
import com.nxy.cpfsfe.busi.bolag.NCSNstrASrvBean;
import com.nxy.cpfsfe.enumtype.*;
import com.nxy.cpfsfe.mybatis.mapper.TbSelfmntnMapper;
import com.nxy.cpfsfe.mybatis.mapper.TdBatchAMapper;
import com.nxy.cpfsfe.mybatis.mapper.TeBatchReqMapper;
import com.nxy.cpfsfe.mybatis.mapper.TsPCmdMapper;
import com.nxy.cpfsfe.mybatis.pojo.*;
import com.nxy.cpfsfe.mybatis.service.TdBatchAService;
import com.nxy.cpfsfe.mybatis.service.TeBatchReqService;
import com.nxy.cpfsfe.util.*;
import com.nxy.cpfsfe.util.sftp.SFTPTransfer;
import com.nxy.cpfsfe.util.zookeeper.DistributedLock;
import com.nxy.cpfsfe.util.zookeeper.ZookeeperLockUtil;
import org.apache.ibatis.session.SqlSession;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.io.File;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * 批量业务处理类
 * @author nxygyzd
 *
 */
public class BatchSettlementProc {
	private static BatchSettlementProc instance = new BatchSettlementProc();
	private BatchSettlementProc(){}
	
	public static  BatchSettlementProc getInstance(){
		return instance;
	}

	private SqlSession mybatisSqlSession;
	
	private final static Logger LOGGER = LoggerFactory.getLogger(BatchSettlementProc.class);
	private final static Logger monitorLOGGER = LoggerFactory.getLogger("monitor");


	/**
	 * 批量结算发送汇兑报文定时函数
	 */
	public void batchSendMessage(){
		LOGGER.info("-------批量结算发送汇兑报文定时函数开始-------");
    	//zookeeper锁定此批次信息
		DistributedLock distributedLock = null;
		try {
			mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
			//查询批量请求信息表中批次状态为初始化的数据信息
			List<TeBatchReq> teReqLists =getInItStatTeBatchReq();
			if(teReqLists!= null && teReqLists.size() >0){
				//根据批次号对批量入账信息进行查找结算状态不为成功的
				for (TeBatchReq teBatchReq : teReqLists) {
					LOGGER.info("批量结算发送汇兑信息，请求系统编号[{}]，批次号[{}]",teBatchReq.getReqSysId(),teBatchReq.getBatNo());
					distributedLock = ZookeeperLockUtil.getInstance().creaZooKeeperLock(StringUtil.trimObject(teBatchReq.getReqSysId())+"TeBatchReq"+teBatchReq.getBatNo());
					if(distributedLock.tryLock()){
						//进行汇兑业务发送
						handleBAtchPoc(teBatchReq);
					}else{
						LOGGER.warn("批量结算发送汇兑报文,批次[{}]正在处理中",teBatchReq.getBatNo());
					}
					distributedLock.unlock();
				}
		
			}
		}catch (BaseException e) {
			LOGGER.error("错误码：[{}],错误信息：[{}]",e.getErrorCode(),e.getErrorDesc());
			LOGGER.error("批量结算发送汇兑报文定时函数异常",e);
		}catch(Exception e){
			LOGGER.error("批量结算发送汇兑报文定时函数异常",e);
		}finally {
			if(distributedLock != null){
				distributedLock.unlock();
			}
			LOGGER.info("---------批量结算发送汇兑报文定时函数结束--------");	
		}


	}
	/**
	 * 批量结算回执定时函数
	 */
	public void batchReT() {
		LOGGER.info("-------批量结算回执定时函数开始-------");
    	//zookeeper锁定此批次信息
		DistributedLock distributedLock = null;
		try {
			mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
			//1、根据查询条件，业务状态0-待处理的批次信息
			List<TeBatchReq> teReqLists =getInItStatTeBatchReq();
			if(teReqLists!= null && teReqLists.size() >0){
				//根据批次号对批量入账信息进行查找结算状态不为成功的
				for (TeBatchReq teBatchReq : teReqLists) {
					LOGGER.info("批量结算回执，请求系统编号[{}]，批次号[{}]",teBatchReq.getReqSysId(),teBatchReq.getBatNo());
					distributedLock = ZookeeperLockUtil.getInstance().creaZooKeeperLock(StringUtil.trimObject(teBatchReq.getReqSysId())+"TeBatchReq"+teBatchReq.getBatNo());
					if(distributedLock.tryLock()){
						//2、根据批次信息，查询明细数据的状态是否未都为终态，成功或者失败
						boolean key = judgeDetailsByBatchNo(teBatchReq,mybatisSqlSession);
						if(key){
							if(SysEcodeEnum.CPFS.getCode().equals(teBatchReq.getReqSysId())){
								updateTeBatchReqBeforeRetrun(teBatchReq);
							}else{
								teBatchReq = updateTeBatchReqBeforeRetrun(teBatchReq);
								bacthRetCreatFileAndRpc(teBatchReq);

							}

						}
					}
					distributedLock.unlock();

				}
			}

			//2、根据查询条件，业务状态1-结算明细处理完成的批次信息
			List<TeBatchReq> teReqIngLists =getIngStatTeBatchReq();
			if(teReqIngLists!= null && teReqIngLists.size() >0){
				//根据批次号对批量入账信息进行查找结算状态不为成功的
				for (TeBatchReq teBatchReq : teReqIngLists){
					LOGGER.info("批量结算回执，请求系统编号[{}]，批次号[{}]",teBatchReq.getReqSysId(),teBatchReq.getBatNo());
					distributedLock = ZookeeperLockUtil.getInstance().creaZooKeeperLock(StringUtil.trimObject(teBatchReq.getReqSysId())+"TeBatchReq"+teBatchReq.getBatNo());
					if(distributedLock.tryLock()){
						bacthRetCreatFileAndRpc(teBatchReq);
					}
					distributedLock.unlock();
				}
			}
		}catch (BaseException e) {
			LOGGER.error("错误码：[{}],错误信息：[{}]",e.getErrorCode(),e.getErrorDesc());
			LOGGER.error("批量结算更新回执定时函数处理失败",e);
		}catch(Exception e){
			LOGGER.error("批量结算更新回执定时函数处理失败",e);
		}finally {
			if(distributedLock != null){
				distributedLock.unlock();
			}
			LOGGER.info("---------批量结算更新回执定时函数结束--------");	
		}
	}
	/**
	 * 生成回执文件并发送报文信息
	 * @param teBatchReq
	 */
	private void bacthRetCreatFileAndRpc(TeBatchReq teBatchReq) {
		try {
			//系统生成对账文件
			creatBatchStlResultFile(teBatchReq);
			batchReTFeToGW(teBatchReq);

		} catch (BaseException e) {
			LOGGER.error("错误码：[{}],错误信息：[{}]",e.getErrorCode(),e.getErrorDesc());
			LOGGER.error("503批量结算通知失败，异常码[{}]，失败原因[{}]",e.getErrorCode(),e.getErrorDesc(),e);
			throw e;
		} catch (Exception e) {
			LOGGER.error("503批量结算通知未知失败",e);
			throw e;
		}

		
	}

	/**
	 * 请求回执成功，更新请求登记表状态为交易成功
	 * @param teBatchReq
	 */
	private void updateTeBatchReqAfterRetrun(TeBatchReq teBatchReq) {
		teBatchReq.setProcSta(TeBatchReqEnum.ProcSta_Success.getCode());
		TeBatchReqService.updateTeBatchReqStatus(teBatchReq);
	}
	/**
	 * 请求回执前，更新请求登记表状态为交易中
	 * @param teBatchReq
	 * @return 
	 */
	private TeBatchReq updateTeBatchReqBeforeRetrun(TeBatchReq teBatchReq) {
		if(SysEcodeEnum.CPFS.getCode().equals(teBatchReq.getReqSysId())){
			//前置发送的业务直接成功并结束
			teBatchReq.setProcSta(TeBatchReqEnum.ProcSta_Success.getCode());
		}else{
			//其他请求系统发送的业务状态修改为结算明细处理完成
			teBatchReq.setProcSta(TeBatchReqEnum.ProcSta_Ing.getCode());
		}
		teBatchReq.setDownLoadFilePath(teBatchReq.getBatNo());
		TeBatchReq countTeBatchReq = new TeBatchReq();
		//请求统计
		countTeBatchReq = countTdBatchAByBathNo(teBatchReq.getReqSysId(),teBatchReq.getBatNo());
		if(countTeBatchReq != null){
			teBatchReq.setbStlTotAmt(countTeBatchReq.getbStlTotAmt());
			teBatchReq.setbStlTotDN(countTeBatchReq.getbStlTotDN());
			teBatchReq.setStlTotAmt(countTeBatchReq.getStlTotAmt());
			teBatchReq.setStlTotDN(countTeBatchReq.getStlTotDN());
		}
		TeBatchReqService.updateTeBatchReq(teBatchReq);
		return teBatchReq;
	}
	/**
	 * 批量明细终态查询定时函数
	 * @throws Exception 
	 */
	public void batchSearch(){
		LOGGER.info("-------批量明细终态查询定时函数-------");
    	//zookeeper锁定此批次信息
		DistributedLock distributedLock = null;
		try {
			mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
			//1、根据查询条件，业务状态0-待处理的批次信息
			List<TeBatchReq> teReqLists =getInItStatTeBatchReq();
			//根据批次号对批量入账信息进行查找结算状态不为成功的
			for (TeBatchReq teBatchReq : teReqLists) {
				distributedLock = ZookeeperLockUtil.getInstance().creaZooKeeperLock(StringUtil.trimObject(teBatchReq.getReqSysId())+"TeBatchReq"+teBatchReq.getBatNo());
				if(distributedLock.tryLock()){
					handleTaBatchAStatus(teBatchReq);
				}
				distributedLock.unlock();
			}
		}catch (BaseException e) {
			LOGGER.error("错误码：[{}],错误信息：[{}]",e.getErrorCode(),e.getErrorDesc());
			LOGGER.error("批量明细终态查询定时函数处理失败",e);
		}catch(Exception e){
			LOGGER.error("批量明细终态查询定时函数处理失败",e);
		}finally {
			if(distributedLock != null){
				distributedLock.unlock();
			}
			LOGGER.info("---------批量明细终态查询定时函数结束--------");	
		}

	
	}
	
	/**
	 * 根据批次号查询业务状态处理中的明细数据
	 * 并查询支付流水表更新业务状态
	 * @param teBatchReq
	 */
	private void handleTaBatchAStatus(TeBatchReq teBatchReq) {
		List<TdBatchA> lists = hanleTdBatchAByBathNo(teBatchReq.getReqSysId(),teBatchReq.getBatNo(),TdBatchAEnum.StlSta_ING.getCode());
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
		//循环组装报文并调用NCS发起汇兑请求，并更新结算状态
		if(lists!= null && lists.size() >0){
			for (TdBatchA tdBatchA : lists) {
				TsPCmdMapper tsPCmdMapper = mybatisSqlSession.getMapper(TsPCmdMapper.class);
				TsPCmd tsPCmd = new TsPCmd();
				//明细表的付款方成员行对应支付流水表分片标识
				//明细表的报文标识号对应支付流水表请求交易流水号
				tsPCmd.setAcqOrgId(tdBatchA.getPyrBNo());
				tsPCmd.setXSeqNo(tdBatchA.getMsgId());
				tsPCmd = tsPCmdMapper.query(tsPCmd);
				if(StatEnum.BIZSTA_SUC.getCode().equals(tsPCmd.getBizSta())){
					//更新成功状态
					tdBatchA.setStlSta(TdBatchAEnum.StlSta_Succ.getCode());
				}else if(StatEnum.BIZSTA_FAIL.getCode().equals(tsPCmd.getBizSta())){
					//更新失败信息
					tdBatchA.setStlSta(TdBatchAEnum.StlSta_Fail.getCode());
					tdBatchA.setErrRsn(tsPCmd.getErrDesc());
				}else{
					continue;
				}	
				tdBatchA.setOldStlSta(TdBatchAEnum.StlSta_ING.getCode());
		        TdBatchAService.updateTdBatchA(tdBatchA);
			}
		}
		
	}

	/**
	 * 根据批次信息，查询明细数据的状态是否未都为终态，成功或者失败
	 * @param teBatchReq
	 * @return 终态true，非终态false
	 */
	private boolean judgeDetailsByBatchNo(TeBatchReq teBatchReq,SqlSession mybatisSqlSession) {
		boolean key = false;
		//明细成功笔数+失败笔数=总笔数时候，返回true，其他时候都返回false
		 TdBatchAMapper tmAMapper = mybatisSqlSession.getMapper(TdBatchAMapper.class);
	     long  resultNum = tmAMapper.countReconEnd(teBatchReq.getReqSysId(),teBatchReq.getBatNo());
	     if(resultNum >0 &&resultNum ==(teBatchReq.getbStlTotDN()+teBatchReq.getStlTotDN())){
	    	 key = true;
	     }
		 return key;
	}

	/**
	 * 发往网关
	 * @throws Exception 
	 */
	private String batchReTFeToGW(TeBatchReq teBatchReq){
   	 	String bizMsg = ResponseUtil.buildStlRstXml(teBatchReq);
		LOGGER.info("503清算结果回执报文：[{}]，回调地址[{}]",bizMsg,teBatchReq.getClbckUrl());
		monitorLOGGER.info("资金归集结果：成功归集笔数[{}]，未归集笔数[{}]",teBatchReq.getStlTotDN(),teBatchReq.getbStlTotDN());
		String tpId = DtaInfo.getInstance().getTpId();
		EPOper.put(tpId, "ReqBean[0].head[0].rcvAppCd",teBatchReq.getReqSysId());
   	 	EPOper.put(tpId, "ReqBean[0].head[0].initrSeqno", teBatchReq.getBatNo());
   	 	EPOper.put(tpId, "ReqBean[0].head[0].reqServCd", MsgCdOrTpEnum.MSGTD_503.getCode());
   	 	EPOper.put(tpId, "ReqBean[0].head[0].sndAppCd", SysEcodeEnum.CPFS.getCode());
   	 	EPOper.put(tpId, "ReqBean[0].head[0].reqUrl",teBatchReq.getClbckUrl());
	    EPOper.getCompSDO(tpId, "ReqBody").setValue("BizMsg",bizMsg);
	    String  rspsCd = RpcCommUtil.getInstance().rpcFeToGW(tpId, RpcOutputInfoEnum.OutputName_Pub_Cpfsgw.getCode(),RpcOutputInfoEnum.OutPutSvr_CpfsFwdThrdPrtS.getCode(),false);
		if(RespCd.NCPI0000.equals(rspsCd)){
			//更新请求表状态
			updateTeBatchReqAfterRetrun(teBatchReq);
		}else{
			updateTeBatchReqAfterRetrunFalse(teBatchReq,bizMsg);
		}
	    return rspsCd;
	}

	/**
	 * 报文发送失败，登记补发信息表
	 * @param teBatchReq
	 * @param bizMsg
	 */
	private void updateTeBatchReqAfterRetrunFalse(TeBatchReq teBatchReq,String bizMsg){
		try{

			//登记补发信息表
			mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
			TbSelfmntnMapper tbSelfmntnMapper = mybatisSqlSession.getMapper(TbSelfmntnMapper.class);
			TbSelfmntn  tbSelfmntn = new TbSelfmntn();
			Date date = new Date();
			Timestamp tmp = new Timestamp(date.getTime());
			tbSelfmntn.setBizId(2);
			tbSelfmntn.setReqUrl(teBatchReq.getClbckUrl());
			tbSelfmntn.setSeqNb(teBatchReq.getBatNo());
			tbSelfmntn.setCpfsD(date);
			tbSelfmntn.setChlXCd(MsgCdOrTpEnum.MSGTD_503.getCode());
			tbSelfmntn.setSndSysId(SysEcodeEnum.CPFS.getCode());
			tbSelfmntn.setRcvSysId(teBatchReq.getReqSysId());
			tbSelfmntn.setMsg(bizMsg);
			tbSelfmntn.setRepFlg("0");
			tbSelfmntn.setRepTMs(0);
			tbSelfmntn.setCreTm(tmp);
			tbSelfmntnMapper.insert(tbSelfmntn);
			//请求表信息变更为补发中

			teBatchReq.setProcSta(TeBatchReqEnum.ProcSta_TimeSend.getCode());
			TeBatchReqMapper tMapper = mybatisSqlSession.getMapper(TeBatchReqMapper.class);
			teBatchReq =tMapper.searchBatchA(teBatchReq);
			teBatchReq.setProcTm(date);
			teBatchReq.setProcSta(TeBatchReqEnum.ProcSta_TimeSend.getCode());
			tMapper.updateTeBatchReqStatus(teBatchReq);
		}catch (Throwable e){
			LOGGER.error("更新数据失败：定时补发登记失败",e);
			throw new BaseException(RespCd.NCPO6050,e,"定时补发登记失败");
		}

	}
	/**
	 * 生成批量回执文件
	 * @param teBatchReq
	 * @return
	 * @throws Exception 
	 */
	private String creatBatchStlResultFile(TeBatchReq teBatchReq) {
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
		List<String> lists = new ArrayList<>();
		StringBuffer sumaryLine = new StringBuffer();
		String date = DateUtil.getDate();
		String time = DateUtil.getSysTime();
		//定义汇总数据
		sumaryLine.append(teBatchReq.getBatNo()).append("|").append(teBatchReq.getMerId()).append("|");
		sumaryLine.append(DateUtil.date2Str(teBatchReq.getStlD(),"yyyyMMdd")).append("|").append(trimObject(teBatchReq.getbStlTotDN())).append("|");
		sumaryLine.append(trimObject(teBatchReq.getbStlTotAmt())).append("|").append(trimObject(teBatchReq.getStlTotAmt())).append("|");
		sumaryLine.append(trimObject(teBatchReq.getStlTotDN())).append("|").append(date).append("|");
		sumaryLine.append(time);
		lists.add(sumaryLine.toString());
		//定义明细数据
		TdBatchA thA = new TdBatchA();
		thA.setBatNo(teBatchReq.getBatNo());
		thA.setReqSysId(teBatchReq.getReqSysId());
		List<TdBatchA> taLists = hanleTdBatchAByPo(thA);
		if(taLists != null &&taLists.size()>0){
			for (TdBatchA tdBatchA : taLists) {
				StringBuffer detailLine = new StringBuffer();
				detailLine.append(trimObject(tdBatchA.getSeqNo())).append("|").append(trimObject(tdBatchA.getxDir())).append("|");
				detailLine.append(trimObject(tdBatchA.getOrdNo())).append("|").append(trimObject(tdBatchA.getpTyp())).append("|");
				detailLine.append(trimObject(tdBatchA.getMerId())).append("|").append(trimObject(tdBatchA.getMerId2())).append("|");
				detailLine.append(trimObject(tdBatchA.getxAmt())).append("|").append(trimObject(tdBatchA.getYrAmt())).append("|");
				detailLine.append(trimObject(tdBatchA.getxAmt2())).append("|").append(trimObject(tdBatchA.getStlSta())).append("|");
				detailLine.append(trimObject(tdBatchA.getErrRsn())).append("|").append(trimObject(tdBatchA.getMerRmk()));
				lists.add(detailLine.toString());
			}
		}
		//文件命名方式待确认
		String fileName = teBatchReq.getReqSysId()+"_"+teBatchReq.getBatNo();
		String filePath = upLoadFileSFtp(lists,fileName);
		return filePath;
	}
	private static String trimObject(Object key){
		return null == key? "" :key.toString();
	}

	/**
	 * 文件下载
	 * @param lists
	 * @param fileName
	 * @return
	 */
	private String upLoadFileSFtp(List<String> lists,String fileName){
		String localfilepath ="";
		ToParm toParmSC = new ToParm();
		toParmSC.setDataTyp("bathfe");
		ToParmMapResultHandler toParmMapResultHandler = new ToParmMapResultHandler();
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
		mybatisSqlSession.select("com.nxy.cpfsfe.mybatis.mapper.ToParmMapper.getConfig", toParmSC, toParmMapResultHandler);

		Map<String,String> configMap = toParmMapResultHandler.getConifg();
		String host = configMap.get("host");
		Integer port = Integer.parseInt(configMap.get("port"));
		String username = configMap.get("username");
		String password ="";
		try {
			password = Encry.decryptString(configMap.get("password"));
		} catch (Exception e) {
			throw new BaseException(RespCd.NCPO5004,e,"文件服务器解密失败");
		}
		Integer timeout =  Integer.parseInt(configMap.get("timeout"));
		String localPath = configMap.get("localUploadPath");
		String filePath = localPath+File.separator+fileName;
		String remotePath = configMap.get("remoteUpPath");
		try {
			FileUtil.writeFile(filePath, lists);
		} catch (Exception e) {
			throw new BaseException(RespCd.NCPS1006,e,"文件写入失败");
		}

		LOGGER.info("MFE配置信息：\nIP={}\n端口={}\n用户={}\n密码={}\n超时时间={}ms\n远程文件路径={}\n本地文件保存路径={}",
			host,port,username,configMap.get("password"),timeout,remotePath,filePath);
        
        SFTPTransfer sftp = new SFTPTransfer();
		try {
	        Map<String, String> resMap  =sftp.uploadFile(host, port, username, "", "", password, timeout, filePath, remotePath);
	        if(resMap != null && null != resMap.get("retCode") ){
	        	String retCode = resMap.get("retCode");
	        	if("1".equals(retCode)){
	        		return localfilepath;
	        	}else{
	        		throw  new Exception(resMap.get("retInfo"));
	        	}
	        }
		} catch (Exception e) {
			throw new BaseException(RespCd.NCPS1002,e,"sftp文件上传失败");
		}

        return null;
        //需要解压调用此方法
	}
	/**
	 * 定时进行汇兑请求
	 * @param teBatchReq
	 */
	 public  void handleBAtchPoc(TeBatchReq teBatchReq) {
		LOGGER.debug("批次号信息[{}]",teBatchReq);
		List<TdBatchA> lists = hanleTdBatchAByBathNo(teBatchReq.getReqSysId(),teBatchReq.getBatNo(),TdBatchAEnum.StlSta_Init.getCode());
		NCSNstrASrvBean bean = new NCSNstrASrvBean();
		//循环组装报文并调用NCS发起汇兑请求，并更新结算状态
		if(lists!= null && lists.size() >0){
			for (TdBatchA tdBatchA : lists) {
				try {
					//组装报文，并调用汇兑请求NCSNstrASrvBean.nCSFeToGW()
					String bizMsg =ResponseUtil.build120Xml(tdBatchA,teBatchReq);
					bean.nCSFeToGW(bizMsg,SysEcodeEnum.CPFS.getCode());
					//根据返回,异步暂时不返回数据
					//updateTdBatchAStlSta(tdBatchA.getId(),TdBatchAEnum.StlSta_Succ.getCode());
				}catch (BaseException e) {
					LOGGER.error("汇兑报文定时函数异常,批次号：[{}],明细流水[{}]",tdBatchA.getBatNo(),tdBatchA.getMsgId());
					LOGGER.error("异常信息为errcode:[{}].错误信息[{}]",e.getErrorCode(),e.getErrorDesc());
					throw e;
				} catch (Throwable e) {
					LOGGER.error("汇兑报文定时函数异常,批次号：[{}],明细流水[{}]",tdBatchA.getBatNo(),tdBatchA.getMsgId());	
					LOGGER.error("异常信息为",e);
					throw new BaseException(RespCd.NCPS2402,e,"120报文发送失败");
				}

			}
		}
			
	}
	/**
	 * 进行批量异步汇兑请求
	 * @param teBatchReq
	 * @throws DocumentException 
	 */
	 public  void handleABatchPoc(TeBatchReq teBatchReq) {
		LOGGER.debug("批次号信息[{}]",teBatchReq);
		List<TdBatchA> lists = hanleTdBatchAByBathNo(teBatchReq.getReqSysId(),teBatchReq.getBatNo(),TdBatchAEnum.StlSta_Init.getCode());
		NCSNstrASrvBean bean = new NCSNstrASrvBean();
		//循环组装报文并调用NCS发起汇兑请求，并更新结算状态
		if(lists!= null && lists.size() >0){
			for (TdBatchA tdBatchA : lists) {
				try {
					//组装报文，并调用汇兑请求NCSNstrASrvBean.nCSFeToGW()
					String bizMsg =ResponseUtil.build120Xml(tdBatchA,teBatchReq,false);
					bean.nCSFeToGW(bizMsg,SysEcodeEnum.CPFS.getCode());
					//根据返回,异步暂时不返回数据
					//updateTdBatchAStlSta(tdBatchA.getId(),TdBatchAEnum.StlSta_Succ.getCode());
				}catch (BaseException e) {
					LOGGER.error("汇兑报文定时函数异常,批次号：[{}],明细流水[{}]",tdBatchA.getBatNo(),tdBatchA.getMsgId());
					LOGGER.error("异常信息为errcode:[{}].错误信息[{}]",e.getErrorCode(),e.getErrorDesc());
					throw e;
				} catch (Throwable e) {
					LOGGER.error("汇兑报文定时函数异常,批次号：[{}],明细流水[{}]",tdBatchA.getBatNo(),tdBatchA.getMsgId());
					LOGGER.error("异常信息为",e);
					throw new BaseException(RespCd.NCPS2402,e,"120报文发送失败");
				}

			}
		}
			
	}
	 /**
	  * 根据批次号查询请求表信息
	  * @param reqSysId
	  * @param batNo
	  * @return
	  */
	 public TeBatchReq queryTeBatchReq(String reqSysId,String batNo) {
		 mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
		 TeBatchReq  teBatchReq = new TeBatchReq();
		 teBatchReq.setBatNo(batNo);
		 teBatchReq.setReqSysId(reqSysId);
		 TeBatchReqMapper tmAMapper = mybatisSqlSession.getMapper(TeBatchReqMapper.class);
		 TeBatchReq teReq = tmAMapper.searchBatchA(teBatchReq);
		 return teReq;
	}

	/**
	 * 统计结算成功和未结算的明细数据信息
	 * @param batchNo
	 * @param reqSysId
	 * @return
	 */
	private TeBatchReq countTdBatchAByBathNo(String reqSysId,String batchNo) {
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
		TdBatchAMapper tmAMapper = mybatisSqlSession.getMapper(TdBatchAMapper.class);
		TeBatchReq teReq = tmAMapper.countTdBatchAByBathNo(reqSysId,batchNo);
		return teReq;
	}
	/**
	 * 查询批量请求信息表中批次状态为初始化的数据信息
	 * @return
	 */
	List<TeBatchReq> getInItStatTeBatchReq() {
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
        TeBatchReqMapper tcrMapper = mybatisSqlSession.getMapper(TeBatchReqMapper.class);
        TeBatchReq teBatchReq = new TeBatchReq();
        teBatchReq.setProcSta(TeBatchReqEnum.ProcSta_Init.getCode());
        List<TeBatchReq>  lists = tcrMapper.queryList(teBatchReq);
        return lists;
	}
	/**
	 * 查询批量请求信息表中批次状态为处理中的数据信息
	 * @return
	 */
	List<TeBatchReq> getIngStatTeBatchReq() {
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
        TeBatchReqMapper tcrMapper = mybatisSqlSession.getMapper(TeBatchReqMapper.class);
        TeBatchReq teBatchReq = new TeBatchReq();
        teBatchReq.setProcSta(TeBatchReqEnum.ProcSta_Ing.getCode());
        List<TeBatchReq>  lists = tcrMapper.queryList(teBatchReq);
        return lists;
	}
	/**
	 * 更新批量入账明细信息的状态
	 * @param msgId
	 * @param trxId
	 * @param stlSta
	 * @param acqOrgId
	 */
	public void updateTdBatchAStlSta(String acqOrgId,String msgId,String trxId,String stlSta,String errDesc) {
		TdBatchA tdA = new TdBatchA();
		tdA.setMsgId(msgId);
		tdA.setSeqNo(trxId);
		tdA.setStlSta(stlSta);
		tdA.setPyrBNo(acqOrgId);
		tdA.setErrRsn(errDesc);
		tdA.setOldStlSta(TdBatchAEnum.StlSta_Init.getCode());
		TdBatchAService.updateTdBatchA(tdA);
	}

	/**
	 * 根据批次号对批量入账明细信息进行查找结算状态初始状态的
	 * @param batNo
	 * @param stlSta
	 * @param reqSysId
	 * @return
	 */
	List<TdBatchA> hanleTdBatchAByBathNo(String reqSysId,String batNo,String stlSta){
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
        TdBatchAMapper tmAMapper = mybatisSqlSession.getMapper(TdBatchAMapper.class);
        TdBatchA  TdBatchA = new TdBatchA();
		TdBatchA.setReqSysId(reqSysId);
        TdBatchA.setBatNo(batNo);
        TdBatchA.setStlSta(stlSta);
        List<TdBatchA>  lists = tmAMapper.queryListByPo(TdBatchA);
        return lists;

	}
	/**
	 * 根据批次号对批量入账明细信息进行查找明细信息
	 * @param tdBatchA
	 */
	List<TdBatchA> hanleTdBatchAByPo(TdBatchA tdBatchA){
		mybatisSqlSession =(SqlSession) SpringUtil.getBean("mybatisSqlSession");
        TdBatchAMapper tmAMapper = mybatisSqlSession.getMapper(TdBatchAMapper.class);
        List<TdBatchA>  lists = tmAMapper.queryListByPo(tdBatchA);
        return lists;
	}

}
